<?php

class Adept_Component_Base 
{
    
    protected $bindings = array();
    protected $id;    
    protected $parent;
    protected $root;
    
    protected $rendererType;
    protected $rendered;
    
    public function __construct()
    {
    }
    
    public function processRequest() 
    {
    }    
    
    public function hasRenderer() 
    {
        return false;
    }    
    
    public function render() 
    {        
        if (!$this->isRendered()) {
            return ;
        }
        if ($this->hasRenderer()) {
            $this->getRenderer()->render($this);
        }
    }
    
    public function findParentByClass($class) 
    {
        $parent = $this->getParent();
        while (!is_null($parent)) {
            if ($parent instanceof $class) {
                return $parent;
            }
            $parent->getParent();
        }
        return null;
    }    

    public function getId() 
    {
        return $this->id;
    }
    
    public function setId($id) 
    {
        if (!is_null($this->getRoot()) && !is_null($this->getRoot()->findChildById($id))) {
            throw new Adept_Component_Exception("Duplicated 'id' property = '{$id}'");
        }
        
        $this->id = $id;
    }
    
    public function getUniqueId() 
    {
        return $this->getRoot()->getUniqueId() .'_' . $this->getId();
    }    
    
    public function getParent() 
    {
        return $this->parent;
    }
    
    public function setParent($parent) 
    {
        $this->parent = $parent;
    }
    
    /**
     * @return Adept_Context
     */
    public function getContext() 
    {
        return Adept_Context::getInstance();
    }    
    
    /**
     * @return Adept_Renderer_Writer
     */
    public function getWriter()
    {
        return new Adept_Renderer_Writer($this->getContext()->getResponse());
    }
    
    public function getBindingString($name) 
    {
        return $this->bindings[$name];
    }

    public function setBindingString($name, $binding) 
    {
        $this->bindings[$name] = $binding;
    }
        
    public function setBindingThis($string) 
    {
        $binding = Adept_Binding_Factory::createValueBinding($string);
        $binding->setValue($this);
    }	
    
    /**
     * @param string $name Binding name
     * @return Adept_Binding_IValue
     */
    public function getValueBinding($name) 
    {
        if (isset($this->bindings[$name])) {
            return Adept_Binding_Factory::createValueBinding($this->bindings[$name]);
        } else {
            return null;
        }
    }
    
    public function getValueOfBinding($name, $default = null) 
    {
        $vb = $this->getValueBinding($name);
        return ($vb != null) ? $vb->getValue() : $default;
    }    

    /**
     * @param string $name Binding name
     * @return Adept_Binding_IMethod
     */
    public function getMethodBinding($name) 
    {
        if (isset($this->bindings[$name])) {
            return Adept_Binding_Factory::createMethodBinding($this->bindings[$name]);
        } else {
            return null;
        }
    }    

    public function isRendered() 
    {
        if (!is_null($this->rendered)) {
            return $this->rendered;
        }
        return $this->getValueOfBinding('rendered', true);
    }
    
    public function setRendered($rendered) 
    {
        $this->rendered = $rendered;
    }
    
    /**
     * @todo Refactoring
     */
    public function getRenderer() 
    {
        // 
        $class = 'Adept_Renderer_' . end(explode("_", get_class($this)));
        return new $class();
    }    
    
    /**
     * @return Adept_Component_Root
     */
    public function getRoot() 
    {
        return $this->root;
    }
    
    public function setRoot($root) 
    {
        $this->root = $root;
    }
    
}